########################################################################
#  Wiizard - A Wii games manager
#  Copyright (C) 2023  CYBERDEViL
#
#  This file is part of Wiizard.
#
#  Wiizard is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Wiizard is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################


from PyQt5.QtWidgets import (
  QDialog,
  QLabel,
  QGridLayout,
  QTabWidget,
  QWidget,
  QComboBox,
  QCheckBox,
  QLineEdit,
  QPushButton,
  QToolButton,
  QFileDialog,
  QSizePolicy
)
from PyQt5.QtGui import QValidator
from PyQt5.QtCore import pyqtSignal, QVariant

from wiizard.models.settings import GameImageSettings
from wiizard import globals as Global
from wiizard.widgets.line import HLine
from wiizard.translations import _


"""
                SETTINGS
  =====================================
  [General] >[Game Images]< [Connection]
  =====================================

  ...

  =====================================
                        [CANCEL] [SAVE]
"""

class GeneralSettings(QWidget):
  """
                SETTINGS
  =====================================
  [General] [Game Images] >[Connection]<
  =====================================

  TODO

  =====================================
                        [CANCEL] [SAVE]
  """

  def __init__(self, parent=None):
    QWidget.__init__(self, parent=parent)

    layout = QGridLayout(self)
    layout.addWidget(QLabel("TODO", self), 0, 0, 3, 3)


class GameImageSettingsView(QWidget):
  """
                SETTINGS
  =====================================
  [General] >[Game Images]< [Connection]
  =====================================

  LANGUAGE
  --------
  Preferred            [ select lang ]
  Fallback             [ none        ]
  Enable any fallback  [X]

  CACHE
  -----
  Location             [/home/user/..]

  =====================================
                        [CANCEL] [SAVE]
  """

  changed = pyqtSignal(bool)

  def __init__(self, parent=None):
    QWidget.__init__(self, parent=parent)

    layout = QGridLayout(self)

    # Language
    label = QLabel(_("<b>Language</b>"), self)
    layout.addWidget(label                , 0, 0, 1, 3)

    # Preferred language combobox
    label  = QLabel(_("Preferred"), self)
    self.preferredCombo = QComboBox(self)
    layout.addWidget(label                , 1, 0, 1, 1)
    layout.addWidget(self.preferredCombo  , 1, 1, 1, 2)

    # Fallback language combobox
    label  = QLabel(_("Fallback"), self)
    self.fallbackCombo = QComboBox(self)
    layout.addWidget(label                , 2, 0, 1, 1)
    layout.addWidget(self.fallbackCombo   , 2, 1, 1, 2)

    # Any fallback checkbox
    label  = QLabel(_("Enable any fallback"), self)
    self.anyFallbackCheck = QCheckBox(self)
    layout.addWidget(label                , 3, 0, 1, 1)
    layout.addWidget(self.anyFallbackCheck, 3, 1, 1, 2)

    # Horizontal line
    line = HLine(self)
    layout.addWidget(line                 , 4, 0, 1, 3)

    # Cache
    label = QLabel(_("<b>Cache</b>"), self)
    layout.addWidget(label                , 5, 0, 1, 3)

    label  = QLabel(_("Location"), self)
    self.cachePathEdit = QLineEdit(self)
    self.cachePathEdit.setReadOnly(True)
    button = QToolButton(self)
    button.setText("..")
    layout.addWidget(label                , 6, 0, 1, 1)
    layout.addWidget(self.cachePathEdit   , 6, 1, 1, 1)
    layout.addWidget(button               , 6, 2, 1, 1)

    self.restoreChanges()

    # Connections
    self.preferredCombo.currentIndexChanged.connect(self.__onPrefLangChanged)
    self.fallbackCombo.currentIndexChanged.connect(self.__onFallbackLangChanged)
    self.anyFallbackCheck.stateChanged.connect(self.__onAnyFallbackChanged)
    button.clicked.connect(self.__onChooseCacheDir)

  def restoreChanges(self):
    # Restore preferred language
    self.preferredCombo.clear()
    #self.preferredCombo.addItem("System", QVariant(None))
    index  = 0
    for i in range(0, len(GameImageSettings.LANGUAGES)):
      lang = GameImageSettings.LANGUAGES[i]
      self.preferredCombo.addItem(lang, QVariant(lang))
      if lang == GameImageSettings.PreferredLang:
        index = i# + 1
    self.preferredCombo.setCurrentIndex(index)

    # Restore fallback language
    self.fallbackCombo.clear()
    self.fallbackCombo.addItem(_("None"), QVariant(None))
    index  = 0
    for i in range(0, len(GameImageSettings.LANGUAGES)):
      lang = GameImageSettings.LANGUAGES[i]
      self.fallbackCombo.addItem(lang, QVariant(lang))
      if lang == GameImageSettings.FallbackLang:
        index = i + 1
    self.fallbackCombo.setCurrentIndex(index)

    # Restore any fallback state
    self.anyFallbackCheck.setChecked(GameImageSettings.AnyFallback)

    # Restore cache path
    self.cachePathEdit.setText(Global.ImageCache.path)

  def __onPrefLangChanged(self, index):
    self.__processChanges()

  def __onFallbackLangChanged(self, index):
    self.__processChanges()

  def __onAnyFallbackChanged(self, state):
    self.__processChanges()

  def __onChooseCacheDir(self):
    dialog = QFileDialog(self, _("Set cache dir"), Global.ImageCache.path)
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    dialog.setFileMode(QFileDialog.Directory)

    if dialog.exec():
      self.cachePathEdit.setText(dialog.directory().path())
      self.__processChanges()

  def __processChanges(self):
    self.changed.emit(self.hasChanges())

  def hasChanges(self):
    if self.preferredCombo.currentData() != GameImageSettings.PreferredLang:
      return True

    if self.fallbackCombo.currentData() != GameImageSettings.FallbackLang:
      return True

    if self.anyFallbackCheck.isChecked() != GameImageSettings.AnyFallback:
      return True

    if Global.ImageCache.path != self.cachePathEdit.text():
      return True

    return False

  def saveChanges(self):
    GameImageSettings.PreferredLang = self.preferredCombo.currentData()
    GameImageSettings.FallbackLang  = self.fallbackCombo.currentData()
    GameImageSettings.AnyFallback   = self.anyFallbackCheck.isChecked()
    Global.ImageCache.setPath(self.cachePathEdit.text())


class ConnectionSettings(QWidget):
  """
                SETTINGS
  =====================================
  [General] [Game Images] >[Connection]<
  =====================================

  PROXY
  -----
  [socks5] [user:pass@host:port       ]
  [X] Proxy DNS

  USERAGENT
  ---------
  [Wiizard                            ]

  =====================================
                        [CANCEL] [SAVE]
  """

  def __init__(self, parent=None):
    QWidget.__init__(self, parent=parent)

    layout = QGridLayout(self)

    # Proxy
    label = QLabel(_("<b>Proxy</b>"), self)
    layout.addWidget(label              , 0, 0, 1, 3)

    self.proxyTypeCombo = QComboBox(self)
    self.proxyEdit      = QLineEdit(self)
    layout.addWidget(self.proxyTypeCombo, 1, 0, 1, 1)
    layout.addWidget(self.proxyEdit     , 1, 1, 1, 2)

    self.proxyDnsCheck  = QCheckBox(_("Proxy DNS"), self)
    layout.addWidget(self.proxyDnsCheck , 2, 0, 1, 3)

    layout.addWidget(HLine(self)        , 3, 0, 1, 3)

    # Useragent
    label = QLabel(_("<b>Useragent</b>"), self)
    layout.addWidget(label              , 4, 0, 1, 3)

    self.useragentEdit = QLineEdit(self)
    layout.addWidget(self.useragentEdit , 5, 0, 1, 3)

    layout.rowStretch(5)

    self.proxyTypeCombo.addItem("http")
    self.proxyTypeCombo.addItem("socks4")
    self.proxyTypeCombo.addItem("socks5")

    self.useragentEdit.setText("Wiizard")


class SettingsDialog(QDialog):
  def __init__(self, parent=None):
    QDialog.__init__(self, parent=parent)

    self.setWindowTitle(_("Settings"))

    layout = QGridLayout(self)

    self.tabWidget     = QTabWidget(self)
    self.tabWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
    self.gameImagesTab = GameImageSettingsView(parent=self)

    #self.tabWidget.addTab(GeneralSettings(parent=self)   , "General")  # TODO
    self.tabWidget.addTab(self.gameImagesTab             , _("Game Images"))
    #self.tabWidget.addTab(ConnectionSettings(parent=self), "Connection")  #TODO

    self.cancelButton = QPushButton(_("Cancel"), self)
    self.saveButton   = QPushButton(_("Save"), self)
    self.saveButton.setEnabled(False)

    layout.addWidget(self.tabWidget   , 0, 0, 1, 4)
    layout.addWidget(self.cancelButton, 1, 2, 1, 1)
    layout.addWidget(self.saveButton  , 1, 3, 1, 1)

    # Connections
    self.cancelButton.clicked.connect(self.__onCancelClicked)
    self.saveButton.clicked.connect(self.__onSaveClicked)
    self.gameImagesTab.changed.connect(self.__onSettingsChanged)

  def __onCancelClicked(self):
    self.close()

  def __onSaveClicked(self):
    if self.gameImagesTab.hasChanges():
      self.gameImagesTab.saveChanges()
    self.close()

  def __onSettingsChanged(self, hasChanges):
    if self.gameImagesTab.hasChanges():
      self.saveButton.setEnabled(True)
    else:
      self.saveButton.setEnabled(False)
